
(function ($, undefined) {
    var requestIndex = 0;
    $.widget("ui.autocomplete", {options:{width:0, appendTo:"body", autoFocus:false, delay:300, minLength:1, position:{my:"left top", at:"left bottom", collision:"none"}, source:null}, pending:0, _create:function () {
        var self = this, doc = this.element[0].ownerDocument, suppressKeyPress;
        this.element.addClass("ui-autocomplete-input").attr("autocomplete", "off").attr({role:"textbox", "aria-autocomplete":"list", "aria-haspopup":"true"}).bind("keydown.autocomplete", function (event) {
            if (self.options.disabled || self.element.propAttr("readOnly")) {
                return;
            }
            suppressKeyPress = false;
            var keyCode = $.ui.keyCode;
            switch (event.keyCode) {
              case keyCode.PAGE_UP:
                self._move("previousPage", event);
                break;
              case keyCode.PAGE_DOWN:
                self._move("nextPage", event);
                break;
              case keyCode.UP:
                self._move("previous", event);
                event.preventDefault();
                break;
              case keyCode.DOWN:
                self._move("next", event);
                event.preventDefault();
                break;
              case keyCode.ENTER:
              case keyCode.NUMPAD_ENTER:
                if (self.menu.active) {
                    suppressKeyPress = true;
                    event.preventDefault();
                }
              case keyCode.TAB:
                if (!self.menu.active) {
                    return;
                }
                self.menu.select(event);
                break;
              case keyCode.ESCAPE:
                self.element.val(self.term);
                self.close(event);
                break;
              default:
                clearTimeout(self.searching);
                self.searching = setTimeout(function () {
                    if (self.term != self.element.val()) {
                        self.selectedItem = null;
                        self.search(null, event);
                    }
                }, self.options.delay);
                break;
            }
        }).bind("keypress.autocomplete", function (event) {
            if (suppressKeyPress) {
                suppressKeyPress = false;
                event.preventDefault();
            }
        }).bind("focus.autocomplete", function () {
            if (self.options.disabled) {
                return;
            }
            self.selectedItem = null;
            self.previous = self.element.val();
        }).bind("blur.autocomplete", function (event) {
            if (self.options.disabled) {
                return;
            }
            clearTimeout(self.searching);
            self.closing = setTimeout(function () {
                self.close(event);
                self._change(event);
            }, 150);
        });
        this._initSource();
        this.response = function () {
            return self._response.apply(self, arguments);
        };
        this.menu = $("<ul></ul>").addClass("ui-autocomplete").appendTo($(this.options.appendTo || "body", doc)[0]).mousedown(function (event) {
            var menuElement = self.menu.element[0];
            if (!$(event.target).closest(".ui-menu-item").length) {
                setTimeout(function () {
                    $(document).one("mousedown", function (event) {
                        if (event.target !== self.element[0] && event.target !== menuElement && !$.ui.contains(menuElement, event.target)) {
                            self.close();
                        }
                    });
                }, 1);
            }
            setTimeout(function () {
                clearTimeout(self.closing);
            }, 13);
        }).menu({focus:function (event, ui) {
            var item = ui.item.data("item.autocomplete");
            if (false !== self._trigger("focus", event, {item:item})) {
                if (/^key/.test(event.originalEvent.type)) {
                    self.element.val(item.value);
                }
            }
        }, selected:function (event, ui) {
            var item = ui.item.data("item.autocomplete"), previous = self.previous;
            if (self.element[0] !== doc.activeElement) {
                self.element.focus();
                self.previous = previous;
                setTimeout(function () {
                    self.previous = previous;
                    self.selectedItem = item;
                }, 1);
            }
            if (false !== self._trigger("select", event, {item:item})) {
                self.element.val(item.value);
            }
            self.term = self.element.val();
            self.close(event);
            self.selectedItem = item;
        }, blur:function (event, ui) {
            if (self.menu.element.is(":visible") && (self.element.val() !== self.term)) {
                self.element.val(self.term);
            }
        }}).zIndex(this.element.zIndex() + 1).css({top:0, left:0}).hide().data("menu");
        if ($.fn.bgiframe) {
            this.menu.element.bgiframe();
        }
    }, destroy:function () {
        this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");
        this.menu.element.remove();
        $.Widget.prototype.destroy.call(this);
    }, _setOption:function (key, value) {
        $.Widget.prototype._setOption.apply(this, arguments);
        if (key === "source") {
            this._initSource();
        }
        if (key === "appendTo") {
            this.menu.element.appendTo($(value || "body", this.element[0].ownerDocument)[0]);
        }
        if (key === "disabled" && value && this.xhr) {
            this.xhr.abort();
        }
    }, _initSource:function () {
        var self = this, array, url;
        if ($.isArray(this.options.source)) {
            array = this.options.source;
            this.source = function (request, response) {
                response($.ui.autocomplete.filter(array, request.term));
            };
        } else {
            if (typeof this.options.source === "string") {
                url = this.options.source;
                this.source = function (request, response) {
                    if (self.xhr) {
                        self.xhr.abort();
                    }
                    self.xhr = $.ajax({url:url, data:request, dataType:"json", autocompleteRequest:++requestIndex, success:function (data, status) {
                        if (this.autocompleteRequest === requestIndex) {
                            response(data);
                        }
                    }, error:function () {
                        if (this.autocompleteRequest === requestIndex) {
                            response([]);
                        }
                    }});
                };
            } else {
                this.source = this.options.source;
            }
        }
    }, search:function (value, event) {
        value = value != null ? value : this.element.val();
        this.term = this.element.val();
        if (value.length < this.options.minLength) {
            return this.close(event);
        }
        clearTimeout(this.closing);
        if (this._trigger("search", event) === false) {
            return;
        }
        return this._search(value);
    }, _search:function (value) {
        this.pending++;
        this.element.addClass("ui-autocomplete-loading");
        this.source({term:value}, this.response);
    }, _response:function (content) {
        if (!this.options.disabled && content && content.length) {
            content = this._normalize(content);
            this._suggest(content);
            this._trigger("open");
        } else {
            this.close();
        }
        this.pending--;
        if (!this.pending) {
            this.element.removeClass("ui-autocomplete-loading");
        }
    }, close:function (event) {
        clearTimeout(this.closing);
        if (this.menu.element.is(":visible")) {
            this.menu.element.hide();
            this.menu.deactivate();
            this._trigger("close", event);
        }
    }, _change:function (event) {
        if (this.previous !== this.element.val()) {
            this._trigger("change", event, {item:this.selectedItem});
        }
    }, _normalize:function (items) {
        if (items.length && items[0].label && items[0].value) {
            return items;
        }
        return $.map(items, function (item) {
            if (typeof item === "string") {
                return {label:item, value:item};
            }
            return $.extend({label:item.label || item.value, value:item.value || item.label}, item);
        });
    }, _suggest:function (items) {
        var ul = this.menu.element.empty().zIndex(this.element.zIndex() + 1);
        this._renderMenu(ul, items);
        this.menu.deactivate();
        this.menu.refresh();
        ul.show();
        this._resizeMenu();
        ul.position($.extend({of:this.element}, this.options.position));
        if (this.options.autoFocus) {
            this.menu.next(new $.Event("mouseover"));
        }
    }, _resizeMenu:function () {
        var ul = this.menu.element;
        ul.outerWidth(Math.max(this.options.width, Math.max(ul.width("").outerWidth(), this.element.outerWidth()+17)));
    }, _renderMenu:function (ul, items) {
        var self = this;
        $.each(items, function (index, item) {
            self._renderItem(ul, item);
        });
    }, _renderItem:function (ul, item) {
        return $("<li></li>").data("item.autocomplete", item).append($("<a></a>").text(item.label)).appendTo(ul);
    }, _move:function (direction, event) {
        if (!this.menu.element.is(":visible")) {
            this.search(null, event);
            return;
        }
        if (this.menu.first() && /^previous/.test(direction) || this.menu.last() && /^next/.test(direction)) {
            this.element.val(this.term);
            this.menu.deactivate();
            return;
        }
        this.menu[direction](event);
    }, widget:function () {
        return this.menu.element;
    }});
    $.extend($.ui.autocomplete, {escapeRegex:function (value) {
        return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\__60__");
    }, filter:function (array, term) {
        var matcher = new RegExp($.ui.autocomplete.escapeRegex(term), "i");
        return $.grep(array, function (value) {
            return matcher.test(value.label || value.value || value);
        });
    }});
}(jQuery));
(function ($) {
    $.widget("ui.menu", {_create:function () {
        var self = this;
        this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox", "aria-activedescendant":"ui-active-menuitem"}).click(function (event) {
            if (!$(event.target).closest(".ui-menu-item a").length) {
                return;
            }
            event.preventDefault();
            self.select(event);
        });
        this.refresh();
    }, refresh:function () {
        var self = this;
        var items = this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role", "menuitem");
        items.children("a").addClass("ui-corner-all").attr("tabindex", -1).mouseenter(function (event) {
            self.activate(event, $(this).parent());
        }).mouseleave(function () {
            self.deactivate();
        });
    }, activate:function (event, item) {
        this.deactivate();
        if (this.hasScroll()) {
            var offset = item.offset().top - this.element.offset().top, scroll = this.element.scrollTop(), elementHeight = this.element.height();
            if (offset < 0) {
                this.element.scrollTop(scroll + offset);
            } else {
                if (offset >= elementHeight) {
                    this.element.scrollTop(scroll + offset - elementHeight + item.height());
                }
            }
        }
        this.active = item.eq(0).children("a").addClass("ui-state-hover").attr("id", "ui-active-menuitem").end();
        this._trigger("focus", event, {item:item});
    }, deactivate:function () {
        if (!this.active) {
            return;
        }
        this.active.children("a").removeClass("ui-state-hover").removeAttr("id");
        this._trigger("blur");
        this.active = null;
    }, next:function (event) {
        this.move("next", ".ui-menu-item:first", event);
    }, previous:function (event) {
        this.move("prev", ".ui-menu-item:last", event);
    }, first:function () {
        return this.active && !this.active.prevAll(".ui-menu-item").length;
    }, last:function () {
        return this.active && !this.active.nextAll(".ui-menu-item").length;
    }, move:function (direction, edge, event) {
        if (!this.active) {
            this.activate(event, this.element.children(edge));
            return;
        }
        var next = this.active[direction + "All"](".ui-menu-item").eq(0);
        if (next.length) {
            this.activate(event, next);
        } else {
            this.activate(event, this.element.children(edge));
        }
    }, nextPage:function (event) {
        if (this.hasScroll()) {
            if (!this.active || this.last()) {
                this.activate(event, this.element.children(".ui-menu-item:first"));
                return;
            }
            var base = this.active.offset().top, height = this.element.height(), result = this.element.children(".ui-menu-item").filter(function () {
                var close = $(this).offset().top - base - height + $(this).height();
                return close < 10 && close > -10;
            });
            if (!result.length) {
                result = this.element.children(".ui-menu-item:last");
            }
            this.activate(event, result);
        } else {
            this.activate(event, this.element.children(".ui-menu-item").filter(!this.active || this.last() ? ":first" : ":last"));
        }
    }, previousPage:function (event) {
        if (this.hasScroll()) {
            if (!this.active || this.first()) {
                this.activate(event, this.element.children(".ui-menu-item:last"));
                return;
            }
            var base = this.active.offset().top, height = this.element.height();
            result = this.element.children(".ui-menu-item").filter(function () {
                var close = $(this).offset().top - base + height - $(this).height();
                return close < 10 && close > -10;
            });
            if (!result.length) {
                result = this.element.children(".ui-menu-item:first");
            }
            this.activate(event, result);
        } else {
            this.activate(event, this.element.children(".ui-menu-item").filter(!this.active || this.first() ? ":last" : ":first"));
        }
    }, hasScroll:function () {
        return this.element.height() < this.element[$.fn.prop ? "prop" : "attr"]("scrollHeight");
    }, select:function (event) {
        this._trigger("selected", event, {item:this.active});
    }});
}(jQuery));

